package spynx.desl.runtime.operators.impl;

import spynx.desl.runtime.IExecutionContext;
import spynx.desl.runtime.IOperator;
import spynx.util.InvalidOperation;

public class ComparisonOperator implements IOperator {

	@Override
	public String getOperator() {
		return "Comparison";
	}

	@SuppressWarnings("rawtypes")
	@Override
	public Object apply(IExecutionContext context, String operator,
			Object... args) {
		Object left = context.resolveValue(args[0]);
		Object right = context.resolveValue(args[1]);
		
		if (left instanceof Comparable)
			return Compare((Comparable)left, right, operator);
		
		return ObjectCompare(left, right, operator);
	}

	private Object ObjectCompare(Object left, Object right, String operator) {
		if ("==".equals(operator))
			return left == right;
		if ("!=".equals(operator))
			return left != right;
		throw new InvalidOperation(operator, left, right);
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	private Object Compare(Comparable left, Object right, String operator) {
		int res = right != null ? left.compareTo(right) : 1;
		
		if (">".equals(operator)) return res > 0;
		if (">=".equals(operator)) return res >= 0;
		if ("<".equals(operator)) return res < 0;
		if ("<=".equals(operator)) return res <= 0;
		if ("!=".equals(operator)) return res != 0;
		if ("==".equals(operator)) return res == 0;
		return null;
	}

}
